#pragma once

#include "sync_queue.h"
#include "thread_helper.h"

class ThreadPool;

class IThreadTask {
public:
    virtual ~IThreadTask() {}
    virtual void OnThread(void* param) = 0;
};

class ThreadPool : public IThreadFunc {
    struct ThreadInfo {
        ThreadHelper* mThread;
        bool mEnable;

        ThreadInfo(ThreadHelper* thread)
            : mThread(thread), mEnable(true) {}
    };

    struct ThreadData {
        IThreadTask* mTask;
        void* mParam;

        ThreadData(IThreadTask* task = NULL, void* param = NULL)
            : mTask(task), mParam(param) {}
    };

public:
    ThreadPool();
    virtual ~ThreadPool();
    void Init(size_t minThreadNum, size_t maxThreadNum);
    void Join();
    void Execute(IThreadTask* task, void* param);

private:
    ThreadPool(const ThreadPool&);
    ThreadPool& operator =(const ThreadPool&);
    virtual void OnThread(const ThreadHelper& sender);
    void AddThread();

protected:
    size_t mMinNum;
    size_t mMaxNum;
    SyncMutex mMutex;
    std::vector<ThreadInfo> mThreads;
    SyncQueue<ThreadData> mTasks;
};
